#include <map>
#include <string>
#include <iostream>
#include <vector>

enum GError {
    GERROR_OK = 0,
    GERROR_API_FAILED = 1,
    GERROR_BINDER_ERROR = 2,
    GERROR_CONNOT_CONNECT_SAMGR = 3,
    GERROR_CONNOT_CONNECT_SERVER = 4,
    GERROR_CONNOT_CONNECT_WESTON = 5,
    GERROR_INNER_ERROR = 6,
    GERROR_INVALID_ARGUMENTS = 7,
    GERROR_INVALID_OPERATING = 8,
    GERROR_NO_BUFFER = 9,
    GERROR_NO_CONSUMER = 10,
    GERROR_NO_ENTRY = 11,
    GERROR_NO_MEM = 12,
    GERROR_NO_PERMISSION = 13,
    GERROR_NOT_INIT = 14,
    GERROR_NOT_SUPPORT = 15,
    GERROR_OUT_OF_RANGE = 16,
    GERROR_PROXY_NOT_INCLUDE = 17,
    GERROR_SERVER_ERROR = 18,
    GERROR_TYPE_ERROR = 19,
    _GMAXERROR,
};

static const std::string GErrorStrs[] = {
    [GERROR_OK] = "",
    [GERROR_API_FAILED] = "<api call failed>",
    [GERROR_BINDER_ERROR] = "<binder occur error>",
    [GERROR_CONNOT_CONNECT_SAMGR] = "<connot connect to samgr>",
    [GERROR_CONNOT_CONNECT_SERVER] = "<connot connect to server>",
    [GERROR_CONNOT_CONNECT_WESTON] = "<connot connect to weston>",
    [GERROR_INNER_ERROR] = "<internal error>",
    [GERROR_INVALID_ARGUMENTS] = "<invalid arguments>",
    [GERROR_INVALID_OPERATING] = "<invalid operating>",
    [GERROR_NO_BUFFER] = "<no buffer>",
    [GERROR_NO_CONSUMER] = "<no consumer>",
    [GERROR_NO_ENTRY] = "<no entry>",
    [GERROR_NO_MEM] = "<no memory>",
    [GERROR_NO_PERMISSION] = "<no permission>",
    [GERROR_NOT_INIT] = "<not init>",
    [GERROR_NOT_SUPPORT] = "<not support>",
    [GERROR_OUT_OF_RANGE] = "<out of range>",
    [GERROR_PROXY_NOT_INCLUDE] = "<proxy not include>",
    [GERROR_SERVER_ERROR] = "<server occur error>",
    [GERROR_TYPE_ERROR] = "<type error>",
};

static inline std::string GErrorStr(GError err)
{
    if (err >= _GMAXERROR) {
        return "<GError error index out of range>";
    }
    return GErrorStrs[err];
}

enum WMError {
    WM_OK = GERROR_OK,
    WM_ERROR_SAMGR = GERROR_CONNOT_CONNECT_SAMGR,
    WM_ERROR_WMS_NOT_FOUND = GERROR_CONNOT_CONNECT_SERVER,
    WM_ERROR_NOT_INIT = GERROR_NOT_INIT,
    WM_ERROR_API_FAILED = GERROR_API_FAILED,
    WM_ERROR_NEW = GERROR_NO_MEM,
    WM_ERROR_INNER = GERROR_INNER_ERROR,
    WM_ERROR_NULLPTR = GERROR_INVALID_ARGUMENTS,
    WM_ERROR_INVALID_PARAM = GERROR_INVALID_ARGUMENTS,
    WM_ERROR_CONNOT_CONNECT_WESTON = GERROR_CONNOT_CONNECT_WESTON,
    WM_ERROR_SERVER = GERROR_SERVER_ERROR,
};

static const std::vector<WMError> WMErrorStrs({
    WM_OK,
    WM_ERROR_SAMGR,
    WM_ERROR_WMS_NOT_FOUND,
    WM_ERROR_NOT_INIT,
    WM_ERROR_API_FAILED,
    WM_ERROR_NEW,
    WM_ERROR_INNER,
    WM_ERROR_NULLPTR,
    WM_ERROR_INVALID_PARAM,
    WM_ERROR_CONNOT_CONNECT_WESTON,
    WM_ERROR_SERVER,
});

static inline std::string WMErrorStr(WMError err)
{
    for (const auto &e : WMErrorStrs) {
        if (e == err) {
            return GErrorStrs[err];
        }
    }
    return "<WMError error index out of range>";
}

int main()
{
    std::cout << WMErrorStr(WM_ERROR_SAMGR) << std::endl;
    std::cout << GErrorStr(GERROR_OK) << std::endl;
    return 0;
}
